package com.author.surface;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.border.LineBorder;
import javax.swing.text.StyleConstants;

import com.author.document.style.StyleChangeNotify;

public final class ToolPanel extends JPanel {
	/** Color of the TOOL PANEL */
	public static final Color	TOOLPANEL_COLOR		= Color.lightGray;

	/** Layout of the Tool Panel */
	private FlowLayout			mainLayout;

	/**
	 * The Tool Panel consists of two tool bars - the top tool bar and the
	 * bottom tool bar. The top tool bar contains the buttons related to file
	 * manipulation, e.g. (Save/Save As/Cut/Copy/Paste etc.) whereas the bottom
	 * tool bar contains the buttons related to document style manipulation e.g.
	 * (Bold/Italic/Underline/Justify etc.)
	 */
	private JPanel				topToolBar			= null;
	private JPanel				bottomToolBar		= null;

	/**
	 * The following buttons are related to setting different document styles,
	 * fonts and choosing corresponding font sizes.
	 */
	private JComboBox			styleSelector;
	private JComboBox			fontSelector;
	private JComboBox			fontSizer;

	/** The buttons for BOLD, ITALIC and UNDERLINE actions */
	private JToggleButton		boldAction;
	private JToggleButton		italicAction;
	private JToggleButton		underlineAction;

	/** The buttons related to superscript and subscript action */
	private JToggleButton		superscriptAction;
	private JToggleButton		subscriptAction;

	/** The buttons related to alignment actions */
	private JToggleButton		alignLeftAction		= AlignActionButtonGroup
															.getAlignLeft();
	private JToggleButton		alignCenterAction	= AlignActionButtonGroup
															.getAlignCenter();
	private JToggleButton		alignRightAction	= AlignActionButtonGroup
															.getAlignRight();
	private JToggleButton		alignJustifyAction	= AlignActionButtonGroup
															.getAlignJustify();

	/** Left and right indent buttons */
	private JButton				leftIndentButton	= new LeftIndentButton();
	private JButton				rightIndentButton	= new RightIndentButton();

	/** The buttons related to line spacing actions */
	private JToggleButton		singlespaceAction	= LineSpacingButtonGroup
															.getSingleSpaceButton();
	private JToggleButton		onehalfspaceAction	= LineSpacingButtonGroup
															.getOneHalfSpaceButton();
	private JToggleButton		doublespaceAction	= LineSpacingButtonGroup
															.getDoubleSpaceButton();

	/** The tool panel will keep a reference to the UI updater */
	private static UIupdater	UI_UPDATE			= UIupdater.getUIupdater();

	/** The buttons for unordered and ordered list insertion */
	private UnorderedList		unorderedList		= new UnorderedList();
	private OrderedList			orderedList			= new OrderedList();

	/** The button for inserting table */
	private TableButton			tblActButton		= new TableButton();

	/** The button for inserting horizontal rule */
	private HRbutton			hruleButton			= new HRbutton();

	/* Color chooser button for foreground color */
	private JButton				fgColorBtn			= new ForegroundColorButton(
															null);

	/* Color chooser button for background color */
	private JButton				bgColorBtn			= new BackgroundColorButton(
															null);

	protected ToolPanel(int width, int height) throws Exception {
		/*
		 * Set size and background color of the Tool Panel
		 */
		setSize(width, height);
		setBackground(TOOLPANEL_COLOR);
		setPreferredSize(new Dimension(getHeight(), getHeight()));

		/*
		 * Set the layout of the Tool Panel. This is the master layout of the
		 * Tool Panel. If a new panel is added to the Tool Panel then that panel
		 * will have its own layout with vertical and horizontal gap defined.
		 */
		mainLayout = new FlowLayout();
		mainLayout.setHgap(1);
		mainLayout.setVgap(0);
		setLayout(mainLayout);

		/*
		 * Initialize the top and the bottom tool bars inside the Tool Panel.
		 */
		topToolBar = new ToolBar(getSize().width, (getSize().height / 2));
		// add(topToolBar);

		/*
		 * The Bottom tool bar will have the same width as that of the Tool
		 * Panel of which it is a part, but it will share the height equally
		 * with the Top tool bar, hence its overall height will the height of
		 * the Tool Panel divided by 2.
		 * 
		 * Tool Panel Height = Top Tool Bar height + Bottom Tool Bar height
		 */
		bottomToolBar = new ToolBar(getSize().width,
				(int) (getSize().height / 0.95));
		add(bottomToolBar);

		// Display all styles which are available with the document
		String[] tt = DocumentStyleComboBox.DOCUMENT_STYLENAMES;
		Object[] o3 = new Object[tt.length];
		for (int i = 0; i < tt.length; i++) {
			o3[i] = tt[i];
		}
		styleSelector = new DocumentStyleComboBox(tt);

		// Get all system font info from the System Property object
		String[] ss = SystemProperty.SYSTEN_FONT_INFO;
		Object[] o = new Object[ss.length];
		for (int i = 0; i < ss.length; i++) {
			o[i] = ss[i];
		}
		fontSelector = new FontSelectorComboBox(o);

		// Add combo box showing list of available font sizes to the user
		Object[] o2 = FontSizeComboBox.FONT_SIZE;
		fontSizer = new FontSizeComboBox(o2);

		/*
		 * Add the combo boxes to an inside panel - and then add the inside
		 * panel to the Tool bar
		 */
		JPanel insideToolBarPanel1 = new JPanel();
		insideToolBarPanel1.add(styleSelector);
		insideToolBarPanel1.add(fontSelector);
		insideToolBarPanel1.add(fontSizer);

		// Set the layout of the inside panel which will have the three combo
		// boxes for - document style, font name and font size selection
		insideToolBarPanel1.setBackground(TOOLPANEL_COLOR);
		FlowLayout layout = new FlowLayout();
		layout.setHgap(2);
		layout.setVgap(0);
		insideToolBarPanel1.setLayout(layout);
		bottomToolBar.add(insideToolBarPanel1);

		/*
		 * Add BOLD, ITALIC, UNDERLINE, SUPERSCRIPT and SUBSCRIPT font action
		 * buttons to an inside panel (insidepanel2)
		 */
		boldAction = new BoldAction();
		italicAction = new ItalicAction();
		underlineAction = new UnderlineAction();
		superscriptAction = new SuperscriptAction();
		subscriptAction = new SubscriptAction();

		/*
		 * Add the font toggle buttons to an inside panel - and then add the
		 * inside panel to the Tool bar
		 */
		JPanel insideToolBarPanel2 = new JPanel();
		insideToolBarPanel2.add(boldAction);
		insideToolBarPanel2.add(italicAction);
		insideToolBarPanel2.add(underlineAction);
		insideToolBarPanel2.add(superscriptAction);
		insideToolBarPanel2.add(subscriptAction);

		// Make the Superscript and the Subscript action button aware of each
		// others existence
		((SuperscriptAction) superscriptAction).setSubscript(subscriptAction);
		((SubscriptAction) subscriptAction).setSuperscript(superscriptAction);

		// Set the layout of the inside panel (insidepanel2) which will have the
		// five font toggle buttons for - BOLD, ITALIC, UNDERLINE, SUPERSCRIPT
		// and SUBSCRIPT and then add it to the Tool Bar
		insideToolBarPanel2.setBackground(TOOLPANEL_COLOR);
		insideToolBarPanel2.setLayout(layout); // reuse earlier layout
		bottomToolBar.add(insideToolBarPanel2);

		/*
		 * Add the alignment action toggle buttons to an inside panel - and then
		 * add the inside panel to the Tool bar
		 */
		JPanel insideToolBarPanel3 = new JPanel(layout); // reuse layout
		insideToolBarPanel3.add(alignLeftAction);
		insideToolBarPanel3.add(alignCenterAction);
		insideToolBarPanel3.add(alignRightAction);
		insideToolBarPanel3.add(alignJustifyAction);

		// Add buttons for left and right indentation
		insideToolBarPanel3.add(leftIndentButton);
		insideToolBarPanel3.add(rightIndentButton);

		// Add the panel containing the alignment buttons to the bottom tool bar
		insideToolBarPanel3.setBackground(TOOLPANEL_COLOR);
		bottomToolBar.add(insideToolBarPanel3);

		/*
		 * Add the line spacing action toggle buttons to an inside panel - and
		 * then add the inside panel to the Tool bar
		 */
		JPanel insideToolBarPanel4 = new JPanel(layout); // reuse layout
		insideToolBarPanel4.add(singlespaceAction);
		insideToolBarPanel4.add(onehalfspaceAction);
		insideToolBarPanel4.add(doublespaceAction);

		// Add the panel containing the alignment buttons to the bottom tool bar
		insideToolBarPanel4.setBackground(TOOLPANEL_COLOR);
		bottomToolBar.add(insideToolBarPanel4);

		/*
		 * Add buttons for unordered and ordered list into an inside panel and
		 * then add the inside panel to the Tool bar
		 */
		JPanel insideToolBarPanel5 = new JPanel(layout);
		insideToolBarPanel5.add(unorderedList);
		insideToolBarPanel5.add(orderedList);

		insideToolBarPanel5.add(tblActButton);
		insideToolBarPanel5.add(hruleButton);

		insideToolBarPanel5.setBackground(TOOLPANEL_COLOR);
		bottomToolBar.add(insideToolBarPanel5);

		/*
		 * The foreground color, background color and the highlighter color
		 * buttons are all added as part of panel 6
		 */
		JPanel insideToolBarPanel6 = new JPanel(layout);
		insideToolBarPanel6.add(fgColorBtn);
		insideToolBarPanel6.add(bgColorBtn);

		insideToolBarPanel6.setBackground(TOOLPANEL_COLOR);
		bottomToolBar.add(insideToolBarPanel6);

		/*
		 * Make Tool Panel visible. This should be added at the last so that the
		 * component repaint happens after all the sub-components have been
		 * added.
		 */
		setVisible(true);

		// initialize non UI related work
		initUI();
	}

	/**
	 * Make the UI updater aware of all the buttons which are responsible for
	 * the maintenance of different styles. The will ensure that when the UI
	 * updater receives a request from Style Observer to change the state of
	 * some button - it can forward that message to that particular button
	 */
	public void initUI() {
		UI_UPDATE.put(StyleChangeNotify.FONT_NAME, fontSelector);
		UI_UPDATE.put(StyleChangeNotify.FONT_SIZE, fontSizer);

		UI_UPDATE.put(StyleChangeNotify.BOLD, boldAction);
		UI_UPDATE.put(StyleChangeNotify.ITALIC, italicAction);
		UI_UPDATE.put(StyleChangeNotify.UNDERLINE, underlineAction);
		UI_UPDATE.put(StyleChangeNotify.SUPERSCRIPT, superscriptAction);
		UI_UPDATE.put(StyleChangeNotify.SUBSCRIPT, subscriptAction);

		UI_UPDATE.put(StyleChangeNotify.LEFT_ALIGN, alignLeftAction);
		UI_UPDATE.put(StyleChangeNotify.CENTER_ALIGN, alignCenterAction);
		UI_UPDATE.put(StyleChangeNotify.RIGHT_ALIGN, alignRightAction);
		UI_UPDATE.put(StyleChangeNotify.JUSTIFY_ALIGN, alignJustifyAction);

		UI_UPDATE.put(StyleChangeNotify.SINGLESPACE, singlespaceAction);
		UI_UPDATE.put(StyleChangeNotify.ONEHALFSPACE, onehalfspaceAction);
		UI_UPDATE.put(StyleChangeNotify.DOUBLESPACE, doublespaceAction);

		UI_UPDATE.put(StyleChangeNotify.FOREGROUND_COLOR, fgColorBtn);
		UI_UPDATE.put(StyleChangeNotify.BACKGROUND_COLOR, bgColorBtn);
	}
}
